//
//  FaceView.swift
//  Happiness
//
//  Created by sdw on 15/11/3.
//  Copyright (c) 2015年 ai.com. All rights reserved.
//

import UIKit

protocol FaceViewDataSource :class{
    func smilenessForFaceView( sender : FaceView)->Double?
}

@IBDesignable
class FaceView: UIView {
    var faceCenter : CGPoint {
        return convertPoint(center, fromView: superview)
    }
    var faceRadius : CGFloat{
        return min(bounds.height,bounds.width)/2*scale
    }
    @IBInspectable
    var scale:CGFloat = 0.8{ didSet{setNeedsDisplay()}}
    @IBInspectable
    var linewidth : CGFloat = 3 { didSet{setNeedsDisplay() } }
    @IBInspectable
    var color : UIColor = UIColor.blueColor() { didSet{setNeedsDisplay() } }
    
    weak var dataSoure:FaceViewDataSource?
    
    private struct Scaling {
        static let FaceRadiusToEyeRadiusRatio : CGFloat = 10
        static let FaceRadiusToEyeOffsetRadio : CGFloat = 3
        static let FaceRadiusToEyeSeparationRatio: CGFloat = 1.5
        static let FaceRadiusToMouthWidthRatio: CGFloat = 1
        static let FaceRadiusToMouthHeightRatio: CGFloat = 3
        static let FaceRadiusToMouthOffsetRatio: CGFloat = 3
    }
    
    private enum Eye{ case Left,Right }
    
    private func bezierPathForEye(whichEye: Eye) ->UIBezierPath{
        let eyeRadius = faceRadius / Scaling.FaceRadiusToEyeRadiusRatio
        let eyeVerticalOffset = faceRadius / Scaling.FaceRadiusToEyeOffsetRadio
        let eyeHorizontalSeparation = faceRadius / Scaling.FaceRadiusToEyeSeparationRatio
        
        var eyeCenter = faceCenter
        eyeCenter.y -= eyeVerticalOffset
        switch whichEye{
        case .Left: eyeCenter.x -= eyeHorizontalSeparation/2
        case .Right: eyeCenter.x += eyeHorizontalSeparation/2
        }
        let path = UIBezierPath(arcCenter: eyeCenter, radius: eyeRadius, startAngle: 0, endAngle: CGFloat(2*M_PI), clockwise: true)
        path.lineWidth = linewidth
       
        return path
    }
    
    func scale(pinchGeture: UIPinchGestureRecognizer){
        switch pinchGeture.state{
            case .Changed:
                 scale *= pinchGeture.scale
                 pinchGeture.scale = 1
            default : break
        }
        
    }
    private func bezierPathForSmile(fractionOfsmile:Double) ->UIBezierPath{
        let mouthWidth = faceRadius / Scaling.FaceRadiusToMouthWidthRatio
        let mouthHeight = faceRadius / Scaling.FaceRadiusToMouthHeightRatio
        let mouthVerticalOffset = faceRadius / Scaling.FaceRadiusToMouthOffsetRatio
        
        let smileHeight = CGFloat(max(min(fractionOfsmile, 1),-1)) * mouthHeight
        
        let start = CGPoint(x:faceCenter.x - mouthWidth/2,y:faceCenter.y + mouthVerticalOffset)
        let end = CGPoint(x:start.x + mouthWidth,y:start.y)
        let cp1 = CGPoint(x: start.x + mouthWidth/3,y:start.y + smileHeight)
        let cp2 = CGPoint(x: end.x - mouthWidth/3, y:cp1.y)
        
        let path = UIBezierPath()
        path.moveToPoint(start)
        path.addCurveToPoint(end, controlPoint1: cp1, controlPoint2: cp2)
        path.lineWidth = linewidth
        return path
    }
    
    
    override func drawRect(rect: CGRect) {
        let facePath = UIBezierPath(arcCenter: faceCenter, radius: faceRadius, startAngle: 0, endAngle: CGFloat(2*M_PI), clockwise: true)
        facePath.lineWidth = linewidth
        color.set()
        facePath.stroke()
        let leftEye = bezierPathForEye(Eye.Left)
        let rightEye = bezierPathForEye(Eye.Right)
        leftEye.stroke()
        rightEye.stroke()
        
        let smileness = dataSoure?.smilenessForFaceView(self) ?? 0.0
        let smile = bezierPathForSmile(smileness)
        smile.stroke()
    }

}
